package com.example.service;

import com.example.model.LaundryOrder;
import com.example.model.User;
import com.example.repository.LaundryOrderRepository;
import com.example.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Optional;

@Service
@Transactional
public class LaundryOrderServiceImpl implements LaundryOrderService {
    
    @Autowired
    private LaundryOrderRepository orderRepository;
    
    @Autowired
    private UserRepository userRepository;
    
    @Override
    public LaundryOrder createOrder(LaundryOrder order) {
        if (order.getOrderNumber() == null || order.getOrderNumber().isEmpty()) {
            order.setOrderNumber(generateOrderNumber());
        }
        return orderRepository.save(order);
    }
    
    @Override
    public LaundryOrder updateOrder(LaundryOrder order) {
        return orderRepository.save(order);
    }
    
    @Override
    public Optional<LaundryOrder> findById(Long id) {
        return orderRepository.findById(id);
    }
    
    @Override
    public Optional<LaundryOrder> findByOrderNumber(String orderNumber) {
        return orderRepository.findByOrderNumber(orderNumber);
    }
    
    @Override
    public Page<LaundryOrder> findAll(Pageable pageable) {
        return orderRepository.findAll(pageable);
    }
    
    @Override
    public Page<LaundryOrder> findByCustomer(User customer, Pageable pageable) {
        return orderRepository.findByCustomer(customer, pageable);
    }
    
    @Override
    public Page<LaundryOrder> findByStatus(LaundryOrder.OrderStatus status, Pageable pageable) {
        return orderRepository.findByStatus(status, pageable);
    }
    
    @Override
    public LaundryOrder updateOrderStatus(Long orderId, LaundryOrder.OrderStatus status) {
        Optional<LaundryOrder> orderOpt = orderRepository.findById(orderId);
        if (orderOpt.isPresent()) {
            LaundryOrder order = orderOpt.get();
            order.setStatus(status);
            return orderRepository.save(order);
        }
        throw new RuntimeException("订单不存在");
    }
    
    @Override
    public LaundryOrder assignWorker(Long orderId, Long workerId) {
        Optional<LaundryOrder> orderOpt = orderRepository.findById(orderId);
        Optional<User> workerOpt = userRepository.findById(workerId);
        
        if (orderOpt.isPresent() && workerOpt.isPresent()) {
            LaundryOrder order = orderOpt.get();
            User worker = workerOpt.get();
            
            if (worker.getRole() == User.UserRole.WORKER) {
                order.setWorker(worker);
                return orderRepository.save(order);
            } else {
                throw new RuntimeException("指定的用户不是工人");
            }
        }
        throw new RuntimeException("订单或工人不存在");
    }
    
    @Override
    public LaundryOrder cancelOrder(Long orderId, String reason) {
        Optional<LaundryOrder> orderOpt = orderRepository.findById(orderId);
        if (orderOpt.isPresent()) {
            LaundryOrder order = orderOpt.get();
            order.setStatus(LaundryOrder.OrderStatus.CANCELLED);
            order.setNotes(order.getNotes() + "\n取消原因: " + reason);
            return orderRepository.save(order);
        }
        throw new RuntimeException("订单不存在");
    }
    
    @Override
    public LaundryOrder completeOrder(Long orderId) {
        return updateOrderStatus(orderId, LaundryOrder.OrderStatus.COMPLETED);
    }
    
    @Override
    public OrderStatistics getOrderStatistics() {
        Long totalOrders = orderRepository.count();
        LocalDateTime startOfDay = LocalDateTime.now().toLocalDate().atStartOfDay();
        LocalDateTime endOfDay = startOfDay.plusDays(1);
        Long todayOrders = orderRepository.countTodayOrders(startOfDay, endOfDay);
        Long pendingOrders = orderRepository.countPendingOrders();
        Double todayRevenue = orderRepository.getTodayRevenue(startOfDay, endOfDay);

        return new OrderStatistics(totalOrders, todayOrders, pendingOrders, todayRevenue);
    }
    
    @Override
    public List<LaundryOrder> findByDateRange(LocalDateTime startDate, LocalDateTime endDate) {
        return orderRepository.findByDateRange(startDate, endDate);
    }
    
    @Override
    public String generateOrderNumber() {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String randomSuffix = String.valueOf((int)(Math.random() * 1000));
        return "LO" + timestamp + String.format("%03d", Integer.parseInt(randomSuffix));
    }
    
    @Override
    public void deleteOrder(Long orderId) {
        orderRepository.deleteById(orderId);
    }

    @Override
    public Long countTotalOrders() {
        return orderRepository.count();
    }

    @Override
    public Page<LaundryOrder> getAllOrders(Pageable pageable) {
        return orderRepository.findAll(pageable);
    }

    @Override
    public Optional<LaundryOrder> getOrderById(Long id) {
        return orderRepository.findById(id);
    }
}
